package com.obas.business.parameterpool.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.ColumnMapRowMapper;

import com.ease.common.util.Detect;
import com.ease.dao.JdbcTemplateDataAccessObject;
import com.ease.platform.access.namedstatement.util.NamedStatementGeneratingUtil;
import com.obas.access.business.service.ParameterPoolAccessService;
import com.obas.access.business.service.ParameterTypeAccessService;
import com.obas.access.business.service.TestcaseScriptAccessService;
import com.obas.business.parameterpool.service.ParameterPoolManagementService;
import com.obas.business.parameterpool.vo.ParameterPoolGrid;
import com.obas.business.parameterpool.vo.ParameterPoolListObject;
import com.obas.model.business.ParameterPool;
import com.obas.model.business.ParameterType;
import com.obas.model.business.TestcaseScript;
import com.obas.type.ParameterSourceType;

public class ParameterPoolManagementServiceImpl extends Detect implements ParameterPoolManagementService {

	private JdbcTemplateDataAccessObject jdbcTemplateDataAccessObject;

	private ParameterTypeAccessService parameterTypeAccessService;

	private ParameterPoolAccessService parameterPoolAccessService;

	private TestcaseScriptAccessService testcaseScriptAccessService;

	public static final String DATA_FIELD_PARAMETER_ID = "PARAMETER_ID";

	public static final String DATA_FIELD_DUMMY_PARAMETER_ID = "$PARAMETER_ID";

	public TestcaseScript findTestcaseScriptByParameterId(long parameterId) {

		List<ParameterPool> parameterPools = parameterPoolAccessService.findByParameterId(parameterId);
		if (notEmpty(parameterPools)) {
			long objectId = firstOne(parameterPools).getObjectId();
			if (objectId > 0) {
				return testcaseScriptAccessService.findById(objectId);
			}
		}
		return null;
	}

	public ParameterPoolGrid findByTestcaseScriptId(long testcaseScriptId) {
		List<ParameterType> parameterTypes = parameterTypeAccessService.findByTestcaseScriptId(testcaseScriptId);

		ParameterPoolGrid parameterPoolGrid = new ParameterPoolGrid();
		parameterPoolGrid.setParameterTypes(parameterTypes);
		//
		Map<String, Object> object = new HashMap<String, Object>();
		object.put("parameterTypes", parameterTypes);

		String sql = NamedStatementGeneratingUtil.generate(ParameterPoolManagementServiceImpl.class, "statement.ParameterPool.find.ftl", object, true);
		// String sql = FreeMarkerUtil.processPath(ParameterPoolManagementServiceImpl.class,
		// "statement.ParameterPool.find.ftl", object);
		//
		Map<String, Object> parameter = new HashMap<String, Object>();
		parameter.put("objectType", ParameterSourceType.TestcaseScript.getValue());
		parameter.put("objectId", testcaseScriptId);
		List<Map<String, Object>> data = this.getJdbcTemplateDataAccessObject().getNamedParameterJdbcTemplate().query(sql, parameter, new ColumnMapRowMapper());
		parameterPoolGrid.setParameters(data);
		return parameterPoolGrid;

	}

	private long newParameterId() {
		return testcaseScriptAccessService.sequence();
	}

	public void save(ParameterPoolListObject parameterPoolListObject) {

		List<ParameterPool> parameterPools = null;
		if (null != parameterPoolListObject && notEmpty(parameterPoolListObject.getParameterPools())) {

			Map<String, Long> parameterIds = new HashMap<String, Long>();

			parameterPools = new ArrayList<ParameterPool>();

			long testcaseScriptId = parameterPoolListObject.getTestcaseScriptId();
			// List<ParameterType> parameterTypes= parameterTypeAccessService.findByTestcaseScriptId(testcaseScriptId);
			//

			long parameterId = 0;
			boolean exists = false;
			for (ParameterPool parameterPool : parameterPoolListObject.getParameterPools()) {
				// parameterPool.setCode(entry.getKey());
				// parameterPool.setValue(entry.getValue());
				parameterId = parameterPool.getParameterId();
				exists = true;
				if (parameterId <= 0) {
					exists = false;
					String index = (int) -parameterId + "";
					if (null == parameterIds.get(index)) {
						parameterId = newParameterId();
						parameterIds.put(index, parameterId);
					} else {
						parameterId = parameterIds.get(index);
					}
				}
				parameterPool.setParameterId(parameterId);
				parameterPool.setObjectId(testcaseScriptId);
				parameterPool.setObjectType(ParameterSourceType.TestcaseScript);
				if (exists) {
					parameterPool = parameterPoolAccessService.update(parameterPool);
				} else {
					parameterPool = parameterPoolAccessService.create(parameterPool);
				}
				parameterPools.add(parameterPool);
			}
		}
		long[] removeParameterIds = parameterPoolListObject.getRemoveParameterIds();
		if (notEmpty(removeParameterIds)) {
			for (long removeParameterId : removeParameterIds) {
				removeByParameterId(removeParameterId);
			}
		}
	}

	public void removeByParameterId(long parameterId) {
		List<ParameterPool> parameterPools = parameterPoolAccessService.findByParameterId(parameterId);
		if (notEmpty(parameterPools)) {
			for (ParameterPool parameterPool : parameterPools) {
				parameterPoolAccessService.remove(parameterPool);
			}
		}

	}

	/**
	 * @return the testcaseScriptAccessService
	 */
	public TestcaseScriptAccessService getTestcaseScriptAccessService() {
		return testcaseScriptAccessService;
	}

	/**
	 * @param testcaseScriptAccessService
	 *            the testcaseScriptAccessService to set
	 */
	public void setTestcaseScriptAccessService(TestcaseScriptAccessService testcaseScriptAccessService) {
		this.testcaseScriptAccessService = testcaseScriptAccessService;
	}

	/**
	 * @return the parameterTypeAccessService
	 */
	public ParameterTypeAccessService getParameterTypeAccessService() {
		return parameterTypeAccessService;
	}

	/**
	 * @param parameterTypeAccessService
	 *            the parameterTypeAccessService to set
	 */
	public void setParameterTypeAccessService(ParameterTypeAccessService parameterTypeAccessService) {
		this.parameterTypeAccessService = parameterTypeAccessService;
	}

	/**
	 * @return the parameterPoolAccessService
	 */
	public ParameterPoolAccessService getParameterPoolAccessService() {
		return parameterPoolAccessService;
	}

	/**
	 * @param parameterPoolAccessService
	 *            the parameterPoolAccessService to set
	 */
	public void setParameterPoolAccessService(ParameterPoolAccessService parameterPoolAccessService) {
		this.parameterPoolAccessService = parameterPoolAccessService;
	}

	/**
	 * @return the jdbcTemplateDataAccessObject
	 */
	public JdbcTemplateDataAccessObject getJdbcTemplateDataAccessObject() {
		return jdbcTemplateDataAccessObject;
	}

	/**
	 * @param jdbcTemplateDataAccessObject
	 *            the jdbcTemplateDataAccessObject to set
	 */
	public void setJdbcTemplateDataAccessObject(JdbcTemplateDataAccessObject jdbcTemplateDataAccessObject) {
		this.jdbcTemplateDataAccessObject = jdbcTemplateDataAccessObject;
	}
}
